package com.woniuxy.portal.utils;

import com.woniuxy.common.RedisConst;
import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * JWT工具类
 */
@Component
@Slf4j
public class JwtUtil {

    //密钥
    private String secret = "1234";
    /**
     * 创建Token的方法
     */
    public String createToken(Map<String, Object> claims) {
        //1.创建JWT构建器，并且设置基本的参数
        JwtBuilder builder = Jwts.builder()
                .signWith(SignatureAlgorithm.HS256, secret)  //签名
                .compressWith(CompressionCodecs.GZIP);   //指定压缩格式
        //添加多个键和值
        if (claims != null) {
            builder.setClaims(claims);
        }
        //返回字符串
        return builder.compact();
    }

    /**
     * 解析Token
     */
    public Jws<Claims> parseToken(String token) {
        return Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token);
    }

    /**
     * 获取指定的值
     */
    public String getValue(String token, String key) {
        //解析Token，判断Token是否合法
        Jws<Claims> claimsJws = parseToken(token);
        //获取载荷
        Claims claims = claimsJws.getBody();
        //获取指定的值
        return claims.get(key).toString();
    }

    @Autowired
    private StringRedisTemplate redisTemplate;
    /**
     * 验证JWT是否有效方法
     */
    public boolean validateToken(String token) {

        try {
            //直接调用上面的方法进行解析
            parseToken(token);
            //拿到 token 解析 判断 redis 是否存在 token 是否过期

            //得到Redis中键
            String userId = getValue(token, "userId");
            String key = RedisConst.USER_TOKEN_PREFIX + ":" + userId;
            //获取Redis中Token
            String redisToken = redisTemplate.opsForValue().get(key);
            //比较是否相等
            return redisToken.equals(token);

        } catch (Exception e) {
            log.info("验证Token失败:{}", e.getMessage());
            return false;
        }
    }

}